package editor3d;

import java_cup.runtime.Symbol;
import java.util.*;
%%
%{
	private LinkedList <String> errLex = new LinkedList<String>();
	private static int linea = 0;
	private static int pos = 0;
	private static String lex = "";
	private static int enter = 0;

	private void doError(String err){
		errLex.add(err);
	}

	public LinkedList <String> getErrLexico(){
		return errLex;
	}
	
    public String getErrores(){
		String cadena="";
                int i;
                int z =errLex.size();
                for(i=0;i < z;i++){
                    cadena = cadena + (String)errLex.get(i)+ "\n";
                }
                return cadena;
	}

	public static int getLinea(){
		return linea+1;
	}

	public static int getPos(){
		pos = pos - enter;
		return pos -1;
	}

	public static String getLexema(){
		return lex;
	}

	private void lexemasPosLine(int yyline, String yytext, int yychar){
		linea = yyline;
		lex = yytext;
		pos = yychar;
	}
%}
%public
%class lexicoTS
%cup
%line
%char
%state COM_LN, COM_BL
%eofval{
	{ return new Symbol(symTS.EOF); }
%eofval}
letra = [A-Za-z]
numero = ([0-9])+
id = ({letra})({letra}|[0-9]|[_])*
%%

<YYINITIAL> String { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.STRING, yytext()); }
<YYINITIAL> print { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.PRINT, yytext()); }
<YYINITIAL> abstract { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.ABSTRACT, yytext()); }
<YYINITIAL> break { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.BREAK, yytext()); }
<YYINITIAL> boolean { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.BOOLEAN, yytext()); }
<YYINITIAL> case { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.CASE, yytext()); }
<YYINITIAL> char { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.CHAR, yytext()); }
<YYINITIAL> class { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.CLASS, yytext()); }
<YYINITIAL> continue { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.CONTINUE, yytext()); }
<YYINITIAL> default { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.DEFAULT, yytext()); }
<YYINITIAL> do { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.DO, new Atributo()); }
<YYINITIAL> double { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.DOUBLE, yytext()); }
<YYINITIAL> extends { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.EXTENDS, yytext()); }
<YYINITIAL> false { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.FALSE, yytext()); }
<YYINITIAL> final { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.FINAL, yytext()); }
<YYINITIAL> float { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.FLOAT, yytext()); }
<YYINITIAL> for { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.FOR, yytext()); }
<YYINITIAL> if { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.IF, yytext()); }
<YYINITIAL> else { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.ELSE, yytext()); }
<YYINITIAL> implements { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.IMPLEMENTS, yytext()); }
<YYINITIAL> import { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.IMPORT, yytext()); }
<YYINITIAL> int { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.INT, yytext()); }
<YYINITIAL> interface { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.INTERFACE, yytext()); }
<YYINITIAL> long { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.LONG, yytext()); }
<YYINITIAL> new { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.NEW, yytext()); }
<YYINITIAL> null { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.NULL, yytext()); }
<YYINITIAL> package { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.PACKAGE, yytext()); }
<YYINITIAL> private { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.PRIVATE, yytext()); }
<YYINITIAL> protected { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.PROTECTED, yytext()); }
<YYINITIAL> public { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.PUBLIC, yytext()); }
<YYINITIAL> return { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.RETURN, yytext()); }
<YYINITIAL> static { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.STATIC, yytext()); }
<YYINITIAL> super { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.SUPER, yytext()); }
<YYINITIAL> switch { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.SWITCH, yytext()); }
<YYINITIAL> this { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.THIS, yytext()); }
<YYINITIAL> true { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.TRUE, yytext()); }
<YYINITIAL> void { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.VOID, yytext()); }
<YYINITIAL> while { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.WHILE, yytext()); }
<YYINITIAL> "." { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.DOT, yytext());  }
<YYINITIAL> ";" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.PTCOMA, yytext());  }
<YYINITIAL> ":" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.DOSPTS, new Atributo(yytext()));  }
<YYINITIAL> "," { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.COMA, yytext());  }
<YYINITIAL> "+" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.MAS, yytext());  }
<YYINITIAL> "-" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.MENOS, yytext());  }
<YYINITIAL> "*" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.MULT, yytext());  }
<YYINITIAL> "%" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.MOD, yytext());  }
<YYINITIAL> "/" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.DIV, new String(yytext()));  }
<YYINITIAL> "&&" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.AND, yytext());  }
<YYINITIAL> "||" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.OR, yytext());  }
<YYINITIAL> "^" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(sym.XOR, yytext());  }
<YYINITIAL> "=" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.IWAL, new Simbolo());  }
<YYINITIAL> "==" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.IWALIWAL, yytext());  }
<YYINITIAL> "!=" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.DIST, yytext());  }
<YYINITIAL> "<" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.MENOR, yytext());  }
<YYINITIAL> ">" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.MAYOR, yytext());  }
<YYINITIAL> "<=" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.MENIWAL, yytext());  }
<YYINITIAL> ">=" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.MAYIWAL, yytext());  }
<YYINITIAL> "(" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.PAB, new Atributo(yytext()));  }
<YYINITIAL> ")" { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.PCE, new Metodo());  }
<YYINITIAL> "{" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.LAB, yytext());  }
<YYINITIAL> "}" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.LCE, yytext());  }
<YYINITIAL> "[" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.CAB, new Atributo(yytext()));  }
<YYINITIAL> "]" { lexemasPosLine(yyline, yytext(), yychar);	return new Symbol(symTS.CCE, yytext());  }
<YYINITIAL> "-=" {  lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.RESTAIWAL, yytext());  }
<YYINITIAL> "+=" {  lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.SUMAIWAL, yytext());  }
<YYINITIAL> "*=" {  lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.MULTIWAL, yytext());  }
<YYINITIAL> "++" {  lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.MASMAS, yytext());  }
<YYINITIAL> "--" {  lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.MENMEN, yytext());  }
<YYINITIAL> "\""([^"\""])*"\"" {  lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.STRDATA, yytext());  }
<YYINITIAL> {id} { lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.ID, yytext());  }
<YYINITIAL> {numero} {  lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.INTDATA, yytext());  }
<YYINITIAL> {numero}("."){numero} {  lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.FLOATDATA, yytext());  }
<YYINITIAL> ('){letra}(') {  lexemasPosLine(yyline, yytext(), yychar); return new Symbol(symTS.CHARDATA, yytext());  }
<YYINITIAL> [\t|\r|\f]* { yychar--; }

<YYINITIAL> "/*"		
{
	yybegin(COM_BL);
}
	<COM_BL> "*" 
	{}
	<COM_BL> "/" 
	{}
	<COM_BL> [^"*/"] 
	{}
<COM_BL> "*/"
{
  yybegin(YYINITIAL);
}

<YYINITIAL> "//" 
{
	yybegin(COM_LN);
}
	<COM_LN> [^\n]
	{}	
<COM_LN> [\n]
{
  yybegin(YYINITIAL);
}

<YYINITIAL> [\n] {yychar = 0;}
<YYINITIAL> [ \t\r\f] { /* ignore white space. */ }
. { lexemasPosLine(yyline, yytext(), yychar);
	doError("Error lexico en la linea: " + (yyline+1) + " y posicion "+ getPos() + ", se encontro el caracter invalido >>"+ yytext() +"<< el cual fue ignorado ");  
	System.out.println("Error lexico en la linea: " + (yyline+1) + " y posicion "+ getPos() + ", "+ yytext() +" encontrado ");
}
